﻿using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using System.Data;
using System.Linq;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.XPath;
using Office = Microsoft.Office.Core;
using Word = Microsoft.Office.Interop.Word;
using Tools = Microsoft.Office.Tools;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Diagnostics;
using eRechnung_3_0.Properties;
using ebDoc = eRechnung_3_0.Globals;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;

namespace eRechnung_3_0
{
	public class InvoiceXML
	{
		#region xPath Definitionen
		
		public const string ebInterface_Version = "/3p02/";
		public const string ebInterface_Version3p0 = @"/3p0/";

		public const string Prefix = "xmlns:eb='http://www.ebinterface.at/schema" + ebInterface_Version + @"'";
		public const string PrefixURLeb = @"http://www.ebinterface.at/schema" + ebInterface_Version + @"";
		public const string PrefixURLsig = @"http://www.w3.org/2000/09/xmldsig#";
		public const string PrefixSchemaLocation = @"http://www.ebinterface.at/schema" + ebInterface_Version + @" http://www.ebinterface.at/schema" + ebInterface_Version + @"Invoice.xsd";
		public const string ebInterface_Stylesheet = @"type='text/xsl' href='http://www.ebinterface.at/download/invoiceexample" + ebInterface_Version + @"invoice.xslt'";

		public const string xPathListLine = "eb:Invoice/eb:Details/eb:ItemList/eb:ListLineItem";
		public const string xPathItemList = "eb:Invoice/eb:Details/eb:ItemList";
		public const string xPathPos = "eb:PositionNumber";
		public const string xPathDesc = "eb:Description";
		public const string xPathArtikelNr = "eb:BillersArticleNumber";
		public const string xPathUnit = "eb:Quantity/@eb:Unit";
		public const string xPathQuantity = "eb:Quantity";
		public const string xPathUnitPrice = "eb:UnitPrice";
		public const string xPathReductionRate = "eb:ReductionRate";
		public const string xPathAmount = "eb:LineItemAmount";
		public const string xPathTaxRate = "eb:TaxRate";

		public const string xPathInvoice = "eb:Invoice";
		public const string xPathBillerName = "//eb:Biller/eb:Address/eb:Name";
		public const string xPathBillerStreet = "//eb:Biller/eb:Address/eb:Street";
		public const string xPathBillerTown = "//eb:Biller/eb:Address/eb:Town";
		public const string xPathBillerZip = "//eb:Biller/eb:Address/eb:ZIP";
		public const string xPathBillerCountry = "//eb:Biller/eb:Address/eb:Country";
		public const string xPathBillerContact = "//eb:Biller/eb:Address/eb:Contact";
		public const string xPathBillerPhone = "//eb:Biller/eb:Address/eb:Phone";
		public const string xPathBillerEmail = "//eb:Biller/eb:Address/eb:Email";
		public const string xPathBillerVATID = "//eb:Biller/eb:VATIdentificationNumber";

		public const string xPathInvRecName = "//eb:InvoiceRecipient/eb:Address/eb:Name";
		public const string xPathInvRecSalute = "//eb:InvoiceRecipient/eb:Address/eb:Salutation";
		public const string xPathInvRecStreet = "//eb:InvoiceRecipient/eb:Address/eb:Street";
		public const string xPathInvRecTown = "//eb:InvoiceRecipient/eb:Address/eb:Town";
		public const string xPathInvRecZip = "//eb:InvoiceRecipient/eb:Address/eb:ZIP";
		public const string xPathInvRecCountry = "//eb:InvoiceRecipient/eb:Address/eb:Country";
		public const string xPathInvRecPhone = "//eb:InvoiceRecipient/eb:Address/eb:Phone";
		public const string xPathInvRecContact = "//eb:InvoiceRecipient/eb:Address/eb:Contact";
		public const string xPathInvRecEmail = "//eb:InvoiceRecipient/eb:Address/eb:Email";
		public const string xPathInvRecVATID = "//eb:InvoiceRecipient/eb:VATIdentificationNumber";
        public const string xPathInvRecBillerID = "//eb:InvoiceRecipient/eb:BillersInvoiceRecipientID";

        
		public const string xPathDocumentType = "//eb:Invoice/@eb:DocumentType";
		public const string xPathDocumentTitle = "//eb:Invoice/@eb:DocumentTitle";
		public const string xPathCurrency = "//eb:Invoice/@eb:InvoiceCurrency";
		public const string xAttrGeneratingSystem = "eb:GeneratingSystem";

		public const string xAttrXmlnseb = "xmlns:eb";
		// public const string xAttrGeneratingSystem = "eb:GeneratingSystem";
		public const string xAttrSchemaLocation = "xsi:schemaLocation";

		public const string xPathInvNumber = "//eb:InvoiceNumber";
		public const string xPathInvDate = "//eb:InvoiceDate";
		public const string xPathDeliveryDate = "//eb:Delivery/eb:Date";
		public const string xPathOrderRefID = "//eb:OrderReference/eb:OrderID";
		public const string xPathOrderRefDate = "//eb:OrderReference/eb:ReferenceDate";
		public const string xPathOrderReference = "//eb:OrderReference";

		public const string xPathPaymtDuedate = "//eb:PaymentConditions/eb:DueDate";
		public const string xPathBankName = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankName";
		public const string xPathBankBLZ = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankCode";
		public const string xPathBankBIC = "eb:Invoice/eb:PaymentMethod/eb:BeneficiaryAccount/eb:BIC";
        public const string xPathBankLand = "eb:Invoice/eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankCode/@eb:BankCodeType";
		public const string xPathBankAcctNr = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankAccountNr";
		public const string xPathBankAcctOwner = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankAccountOwner";
		public const string xPathBankIBAN = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:IBAN";
		public const string xPathPaymtMethode = "//eb:PaymentMethod";

		public const string xPathSignature = "//dsig:Signature";
		public const string xPathCertificate = "/eb:Invoice/dsig:Signature/dsig:KeyInfo/dsig:X509Data/dsig:X509Certificate";

		public const string xPathDiscntPmntCond = "eb:Invoice/eb:PaymentConditions";
		public const string xPathDiscntLine = "eb:Invoice/eb:PaymentConditions/eb:Discount";
		public const string xPathDiscntProz = "eb:Percentage";
		public const string xPathDiscntDate = "eb:PaymentDate";
		public const string DueDateXML = "<eb:DueDate>{0}</eb:DueDate>";
		public const string DiscItemXML = "<eb:Discount>" +
										  "<eb:PaymentDate>{0}</eb:PaymentDate>" +
										  "<eb:Percentage>{1}</eb:Percentage>" +
										  "<eb:Amount>{2}</eb:Amount>" +
										  "</eb:Discount>";


		public const string xPathTaxVATList = "//eb:Tax/eb:VAT";

		public const string xPathTotGrossAmount = "//eb:TotalGrossAmount";

		private const string VatItemXML = "<eb:Item>" +
				"<eb:TaxedAmount>{0}</eb:TaxedAmount>" +
				"<eb:TaxRate>{1}</eb:TaxRate>" +
				"<eb:Amount>{2}</eb:Amount>" +
				"</eb:Item>";

		/*
		 * Templates für ListLineItem
		 * */
		private const string DetailItemXml = "<eb:ListLineItem>" +
			"<eb:PositionNumber>{0}</eb:PositionNumber>" +
			"<eb:Description>{1}</eb:Description>" +
			"<eb:BillersArticleNumber>{2}</eb:BillersArticleNumber>" +
			"<eb:Quantity eb:Unit='{3}'>{4}</eb:Quantity>" +
			"<eb:UnitPrice>{5}</eb:UnitPrice>" +
			"<eb:TaxRate>{6}</eb:TaxRate>" +
			"<eb:DiscountFlag>{7}</eb:DiscountFlag>" +
			"<eb:ReductionRate>{8}</eb:ReductionRate>" +
			"<eb:LineItemAmount>{9}</eb:LineItemAmount>" +
			"</eb:ListLineItem>";

		private string DocumentTitle = "";
		private const string _DocumentTitleVorlage = "XML Vorlage für ebInterface 3.0 Word";
		private const string _DocumentTitleFInal = "";

		public enum SaveMethodeTypes { AsUnsignedInvoice = 0, AsTemplate, SignAndMail2TestSystem,SignAndMail2Production }
		public SaveMethodeTypes SaveMethodeType {get;set;}

		public enum TemplateTypes { Empty, FromFile };
		public enum RequireDBCopy { False, True };


		#endregion

		private object missing = Type.Missing;

		public string InvCurrency;
		public string InvBillerCountry;
		public string InvRecipientCountry;
		public string InvBankCountry;
		public string InvDocType;
		public string InvDocTitle;

		private const string CCTag_NichtLeer = "Nicht Leer";
		private const string CCTag_BundNichtLeer = "Bund nicht leer";
		private const string CCTag_VAT = "VAT";
		private const string CCTag_Num = "Numerisch";
		//private const string CCTag_BuKreis = "Buchungskreis";
		//private const string CCTag_OrderID = "OrderRef";
		private const string InvoiceXSDFile = "eRechnung_3_0.Invoice.xsd";
		private const string xmlDsigXSDFile = "eRechnung_3_0.W3C-XMLDSig.xsd";
		public const string ebInterfaceLeer = "eRechnung_3_0.ebInterface30_Leer.xml";
		public const string XMLSignRequest = "eRechnung_3_0.XMLSignRequest.xml";
		public DsInvoice InvDetails;

		private string strLocalFilename;
		private bool bSaveLocal;
		private string strEMailAddress;
		private bool bSendMail;
		private string strEtresorAddress;
		private bool bSendEtresor;

		public InvoiceXML()
		{
			InvDetails = new DsInvoice();
		}


		public Office.CustomXMLPart AddCustomXmlPart(string xmlData)
		{
			// System.Diagnostics.Debugger.Break();
			// Office.CustomXMLPart InvoiceXMLPart;
			

			try
			{
				if (xmlData != null)
				{

					if (ebDoc.ThisDocument.InvoiceXMLPartID == null)
					{
						ebDoc.ThisDocument.InvoiceXMLPart = ebDoc.ThisDocument.CustomXMLParts.Add(xmlData, missing);
						ebDoc.ThisDocument.InvoiceXMLPartID = ebDoc.ThisDocument.InvoiceXMLPart.Id;
						ebDoc.ThisDocument.SetCustomXMLID(ebDoc.ThisDocument.InvoiceXMLPartID);                        
					}
					else
					{
						ebDoc.ThisDocument.InvoiceXMLPart = ebDoc.ThisDocument.CustomXMLParts.SelectByID(ebDoc.ThisDocument.InvoiceXMLPartID);
					}
					ebDoc.ThisDocument.UnprotectDoc();
					ebDoc.ThisDocument.InvoiceXMLPart.NamespaceManager.AddNamespace("eb", InvoiceXML.PrefixURLeb);
					// ebDoc.ThisDocument.ProtectDoc();
					
					return (ebDoc.ThisDocument.InvoiceXMLPart);
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message + "\r\n" + ex.Source + "\r\n" + ex.StackTrace);
				//throw;
			}
			return (null);
		}

		/// <summary>
		/// 
		/// Speicher den angegebene CustomXMLPart als XML Datei
		/// </summary>
		/// <param name="XMLPart">Der zu speichernde CustomXMLPart</param>
		public void SaveXML(Office.CustomXMLPart XMLPart)
		{
			DialogResult dResult;
			if (SaveMethodeType!=SaveMethodeTypes.AsTemplate)
			{
				string CC_Verify = VerifyAllCC();
				if (CC_Verify != "")
				{
					ebDoc.ThisDocument.SetFehlerText(CC_Verify);
					ShowDataError();
					return;
				}

			}
			
			Word.Document wDoc = ebDoc.ThisDocument.Application.ActiveDocument;
			string retVal = string.Empty;
			foreach (Word.ContentControl wCC in wDoc.ContentControls)
			{
				string xPathInXml = wCC.XMLMapping.XPath;
				if (xPathInXml!=null)
				{
					// Code do mke shure that changed fields are put inside CustomXML
					Office.CustomXMLNode xNode = ebDoc.ThisDocument.InvoiceXMLPart.SelectSingleNode(xPathInXml);
					Debug.WriteLine("Update: " + wCC.PlaceholderText.Value + "/" + wCC.Tag + "<" + wCC.Range.Text + "> " + xPathInXml + "=<" + xNode.Text + ">");
					if ((wCC.ShowingPlaceholderText!=true) && (xNode.Text != wCC.Range.Text))
					{
						ebDoc.ThisDocument.UnprotectDoc();
						xNode.Text = wCC.Range.Text;
						ebDoc.ThisDocument.ProtectDoc();
					}

				}
			}
			
			XmlDocument xdoc = new XmlDocument();
			// xdoc.PreserveWhitespace = true;
			XmlNamespaceManager xNMgr = new XmlNamespaceManager(xdoc.NameTable);
			xNMgr.AddNamespace("eb", PrefixURLeb);
			xNMgr.AddNamespace("dsig", PrefixURLsig);
			XmlNode xn;

			// Daten aufbauen
			try
			{
				string ItemXML = string.Empty;
				xdoc.LoadXml(XMLPart.XML);
				xdoc.CreateXmlDeclaration("1.0", "utf-8", string.Empty);

				xn = xdoc.SelectSingleNode(xPathBillerCountry, xNMgr);
				xn.InnerText = InvBillerCountry;
				xn = xdoc.SelectSingleNode(xPathSignature, xNMgr);
				if (xn!=null)
				{
					Debug.WriteLine("gelöscht: " + xn.InnerXml);
					xn.ParentNode.RemoveChild(xn);
				}

				xdoc.SelectSingleNode(xPathBankLand, xNMgr).InnerText = InvBankCountry;
				xdoc.SelectSingleNode(xPathCurrency, xNMgr).InnerText = InvCurrency;
				xdoc.SelectSingleNode(xPathInvRecCountry, xNMgr).InnerText = InvRecipientCountry;
				xdoc.SelectSingleNode(xPathDocumentType, xNMgr).InnerText = InvDocType;
				xdoc.SelectSingleNode(xPathDocumentTitle, xNMgr).InnerText = InvDocTitle;
				string[] tempSVN = ebDoc.ThisDocument.GetSVNInfo().Split(';');
				if (SaveMethodeType!=SaveMethodeTypes.AsTemplate)
				{
					DocumentTitle = ebDoc.ThisDocument.GetAsmTitle();
				}
				else
				{
					DocumentTitle = _DocumentTitleVorlage;
				}

				xdoc.DocumentElement.Attributes[xAttrGeneratingSystem].InnerText = DocumentTitle + " " + tempSVN[0]; ;
				// xdoc.SelectSingleNode(xAttrGeneratingSystem, xNMgr).InnerText = DocumentTitle+" "+tempSVN[0];
				xdoc.SelectSingleNode(xPathInvDate, xNMgr).InnerText = FormatDateVonXML(xdoc.SelectSingleNode(xPathInvDate, xNMgr).InnerText);
				xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr).InnerText = FormatDateVonXML(xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr).InnerText);
				xdoc.SelectSingleNode(xPathOrderRefDate, xNMgr).InnerText = FormatDateVonXML(xdoc.SelectSingleNode(xPathOrderRefDate, xNMgr).InnerText);
				xdoc.SelectSingleNode(xPathTotGrossAmount, xNMgr).InnerText = FormatDecimal(ebDoc.ThisDocument.BetragInklMwSt);
				ItemXML = Details2XML();
				XmlNode ItemNode = xdoc.SelectSingleNode(xPathItemList, xNMgr);
				ItemNode.InnerXml = ItemXML;

				ItemXML = MwSt2XML();
				ItemNode = xdoc.SelectSingleNode(xPathTaxVATList, xNMgr);
				ItemNode.InnerXml = ItemXML;

				ItemNode = xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr);
                ItemXML = Skonto2XML();
                ItemXML = string.Format(DueDateXML, ItemNode.InnerXml) + ItemXML;
				ItemNode = xdoc.SelectSingleNode(xPathDiscntPmntCond, xNMgr);
				ItemNode.InnerXml = ItemXML;

				// Kein Löschen von leeren Nodes bei speichern als XML Vorlage
				if (SaveMethodeType!=SaveMethodeTypes.AsTemplate)
				{
					wDoc = ebDoc.ThisDocument.Application.ActiveDocument;
					string wCCNode = string.Empty;
					foreach (Word.ContentControl wCC in wDoc.ContentControls)
					{
						wCCNode = wCC.XMLMapping.XPath;
						Debug.WriteLine(wCC.PlaceholderText.Value+";"+wCCNode+";<"+wCC.Tag+">");
						
						if ((wCCNode!=null)&&(wCC.Tag==null))    // optionale Node
						{
							xn = xdoc.SelectSingleNode(wCCNode, xNMgr);
							if (xn.InnerText=="")
							{
								xn.ParentNode.RemoveChild(xn);

							}
						}
					}
					// Test ob xPathOrderReference xPathPaymtMethode leer sind
					xn = xdoc.SelectSingleNode(xPathOrderReference, xNMgr);
					if ((xn != null) && ((xn.InnerXml == "")||(xn.InnerText=="")))
					{
						xn.ParentNode.RemoveChild(xn);
					}

					xn = xdoc.SelectSingleNode(xPathPaymtMethode, xNMgr);
					if ((xn != null) && (xn.InnerText == ""))
					{
						xn.ParentNode.RemoveChild(xn);
					}

				}

			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler bei XML Verarbeitung.\r\n" + ex.Message);
				return;
			}
			if (SaveMethodeType!=SaveMethodeTypes.AsTemplate)       // wenn als Vorlage zu speichern, keine Validierung
			{
				string Tmp2Filename = System.IO.Path.GetTempFileName();  // Temporaeren Dateinamen wählen

				xdoc.Save(Tmp2Filename);

				bool isValid = IsEbInterfaceXMLValid(xdoc, Tmp2Filename, false);
				if (isValid == false)
				{
					ShowDataError();
					return;
				}
				
			}
			if ((SaveMethodeType==SaveMethodeTypes.SignAndMail2Production) || (SaveMethodeType==SaveMethodeTypes.SignAndMail2TestSystem))
			{
				ebInterfaceXMLSign RR = new ebInterfaceXMLSign();
				if (SaveMethodeType == SaveMethodeTypes.SignAndMail2TestSystem)
				{
					RR.Target = ebInterfaceXMLSign.RequestTarget.TestSystem;
				}
				else
				{
					RR.Target = ebInterfaceXMLSign.RequestTarget.ProductionSystem;
				}
				
				XmlDocument signedXML = new XmlDocument();
				signedXML.PreserveWhitespace = true;
				try
				{
#if DEBUG && SAVE_HTML
					RR.savehtml(xdoc.InnerXml, "xdocBeforeSign.xml");
#endif
				   signedXML = RR.SignXML(xdoc);
				   if (signedXML==null)
				   {
					   return;
				   }
#if DEBUG && SAVE_HTML
				   RR.savehtml(signedXML.OuterXml, "signedAfterReturn.xml");
#endif
				   xNMgr = new XmlNamespaceManager(signedXML.NameTable);
				   xNMgr.AddNamespace("eb", PrefixURLeb);
				   xNMgr.AddNamespace("dsig", PrefixURLsig);
				   XmlDeclaration xdeclare;
				   xdeclare = signedXML.CreateXmlDeclaration("1.0", "utf-8", string.Empty);
				   XmlElement root = signedXML.DocumentElement;
				   signedXML.InsertBefore(xdeclare, root);

				   XmlProcessingInstruction xproc;
				   xproc = signedXML.CreateProcessingInstruction("xml-stylesheet", ebInterface_Stylesheet);
				   //xdoc.AppendChild(xproc);
				   signedXML.InsertBefore(xproc, root);

				  dResult = ShowSignResult(signedXML, xNMgr);
				  if (dResult!=DialogResult.OK)
				  {
					  return;
				  }
				   if (bSaveLocal == true)
				   {
					   // signedXML.Save(strLocalFilename);
					   XmlWriter xWrt = XmlWriter.Create(strLocalFilename);
					   signedXML.WriteContentTo(xWrt);
					   xWrt.Close();
					   
					   MessageBox.Show("ebInterface Rechnung gespeichert unter " + strLocalFilename);
				   }
#if NO_ETRESOR
				   bSendEtresor = false;
#endif
				   if ((bSendEtresor == true) || (bSendMail == true))
				   {

					   string subj = ReplaceToken(Settings.Default.setBetreff, signedXML, xNMgr);
					   string MText = ReplaceToken(Settings.Default.setMailText, signedXML, xNMgr);
					   // ToDo wenn lokal nicht gespeichert wurde, in Tempfile speichern. System.IO.Path.GetTempFileName()
					   string sendFilename = System.IO.Path.GetTempFileName();
					   if (bSaveLocal != true)
					   {
						   XmlWriter xWrt = XmlWriter.Create(sendFilename);
						   signedXML.WriteContentTo(xWrt);
						   xWrt.Close();
					   }
					   else
					   {
						   sendFilename = strLocalFilename;
					   }
#if DEBUG  && SAVE_HTML
					   MessageBox.Show("Mail senden an: " + strEMailAddress + "\r\n" +
						   "e-Tresor: " + strEtresorAddress + "\r\n" +
						   subj + "\r\n" + MText);
#endif
					   strEtresorAddress = "";
#if !NO_ETRESOR
					   if (bSendEtresor == false)
					   {
						   strEtresorAddress = "";
					   }
#endif
					   if (bSendMail == false)
					   {
						   strEMailAddress = "";
					   }
					   SendMail(strEMailAddress, strEtresorAddress, subj, MText, sendFilename);
				   }
				   return;
				}
				catch (Exception ex)
				{
					string msg = ex.Message;
#if DEBUG  && SAVE_HTML
					msg = msg + "\r\n" + ex.StackTrace;
					Debug.WriteLine(msg);
#endif
					MessageBox.Show(ex.Message, "Signieren und Versenden");
					return;
				}
				
				
			}
			string XMLFile = string.Empty;
			// StreamWriter XMLWriter;

			SaveFileDialog sDlg = new SaveFileDialog();

			if (SaveMethodeType == SaveMethodeTypes.AsTemplate)
			{
				sDlg.InitialDirectory = Settings.Default.setTemplatePath;
			}
			else
			{
				sDlg.InitialDirectory = Settings.Default.setLocalPath;
			}

			sDlg.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
			sDlg.FilterIndex = 1;
			sDlg.RestoreDirectory = true;

			try
			{
				if (sDlg.ShowDialog() == DialogResult.OK)
				{
					if (File.Exists(sDlg.FileName))
					{
						File.Delete(sDlg.FileName);
					}
					WriteXML(xdoc, sDlg.FileName);
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "Save As XML");
			}
		}

		private void ShowDataError()
		{
			MessageBox.Show("Bei der Datenprüfung wurden Fehler gefunden.\r\n" +
	"Details finden Sie auf Seite 2 dieses Formulars.\r\n",
				  "ebInterface prüfen", MessageBoxButtons.OK, MessageBoxIcon.Error);

			Globals.ThisDocument.Bookmarks["Fehlerliste"].Select();
			return;

		}
		private void WriteXML(XmlDocument xdoc, string filename)
		{
			XmlWriterSettings xwsetting = new XmlWriterSettings();
			xwsetting.Indent = true;
			xwsetting.NewLineChars = Environment.NewLine;
			XmlWriter myXMLWriter = XmlTextWriter.Create(filename, xwsetting);
			xdoc.Save(myXMLWriter);
			myXMLWriter.Close();
			myXMLWriter.Flush();

		}

		private string ReplaceToken(string source, XmlDocument xdoc, XmlNamespaceManager xNmgr)
		{
			string[] Tokens = {"[RECHNUNGSNR]", "[RECHNUNGSDATUM]","[RECHNUNGSSTELLER]","[KONTAKT]","[TELEFON]","[EMAIL]"};
			string[] TkxPath = { xPathInvNumber, xPathInvDate, xPathBillerName, xPathBillerContact, xPathBillerPhone, xPathBillerEmail };
			string tmpString = source;
			for (int i = 0; i < Tokens.Length; i++)
			{
				XmlNode xn = xdoc.SelectSingleNode(TkxPath[i], xNmgr);
				string replText = "-";
				if (xn!=null)
				{
					replText = xn.InnerText;
				}
				tmpString = tmpString.Replace(Tokens[i], replText);
			}
			return tmpString;
		}
		private DialogResult ShowSignResult(XmlDocument signedDoc, XmlNamespaceManager SignedMgr)
		{
			string signer = "";
			string issuer = "";

			string certstr = GetItem(signedDoc, SignedMgr, @"/eb:Invoice/dsig:Signature/dsig:KeyInfo/dsig:X509Data/dsig:X509Certificate");

			if (certstr != null)
			{
				byte[] certbyte = Convert.FromBase64String(certstr);
				X509Certificate2 cert = new X509Certificate2(certbyte);
				signer = cert.SubjectName.Name;
				issuer = cert.IssuerName.Name;
				XmlNode ndKeyInfo = signedDoc.SelectSingleNode(@"/eb:Invoice/dsig:Signature/dsig:KeyInfo", SignedMgr);
				XmlElement elKeyName = signedDoc.CreateElement("dsig", "KeyName", PrefixURLsig);
				elKeyName.InnerText = signer;
				ndKeyInfo.AppendChild(elKeyName);
			}


			FrmConfirm DlgConfirm = new FrmConfirm();
			// AnzPos
			XmlNodeList LineItems = signedDoc.SelectNodes(xPathListLine, SignedMgr);
			DlgConfirm.strAnzPos = LineItems.Count.ToString("D");
			DlgConfirm.strEMailAddress = GetItem(signedDoc, SignedMgr, xPathInvRecEmail);
			if (DlgConfirm.strEMailAddress!="")
			{
				DlgConfirm.bSendMail = true;
			}
			DlgConfirm.strGesBetrag = GetItem(signedDoc, SignedMgr, InvoiceXML.xPathCurrency) + " " + GetItem(signedDoc, SignedMgr, InvoiceXML.xPathTotGrossAmount);
			DlgConfirm.strReEmpfaenger = GetItem(signedDoc, SignedMgr, InvoiceXML.xPathInvRecName);
			DlgConfirm.strReNr = GetItem(signedDoc, SignedMgr, InvoiceXML.xPathInvNumber);
			DlgConfirm.strReDatum = GetItem(signedDoc, SignedMgr, xPathInvDate);
			DlgConfirm.strReSteller = GetItem(signedDoc, SignedMgr, InvoiceXML.xPathBillerName);
			
			DlgConfirm.strSignator = signer;
			DlgConfirm.strZertIssuer = issuer;
			
			DlgConfirm.bSendEtresor = Settings.Default.setSendEtresor;
			DlgConfirm.strEtresorAddress = Settings.Default.setEtresorMail;

			DlgConfirm.bSaveLocal = Settings.Default.setSaveLocal;
			strLocalFilename = MakeFileName(DlgConfirm.strReNr, DlgConfirm.strReDatum);

			DlgConfirm.strLocalFilename = Path.Combine(Settings.Default.setLocalPathSigned, strLocalFilename);

			DialogResult dRC = DlgConfirm.ShowDialog();
			if (dRC!=DialogResult.OK)
			{
				bSaveLocal = false;
				bSendEtresor = false;
				bSendMail = false;
				return dRC;
			}
			bSaveLocal = DlgConfirm.bSaveLocal;
			bSendEtresor = DlgConfirm.bSendEtresor;
			bSendMail = DlgConfirm.bSendMail;
			strEMailAddress = DlgConfirm.strEMailAddress;
			strEtresorAddress = DlgConfirm.strEtresorAddress + "@e-tresor.at";
			if (bSaveLocal==true)
			{
				strLocalFilename = DlgConfirm.strLocalFilename; 
			}
			return dRC;
		}

		private string MakeFileName(string ReNr, string ReDatum)
		{
			string fn = ReNr.Trim(Path.GetInvalidFileNameChars()) + "-" + ReDatum.Trim('-')+".XML";
			return fn;
		}
		private string GetItem(XmlDocument xdoc, XmlNamespaceManager nMgr, string xpath)
		{
			XmlNode node = xdoc.SelectSingleNode(xpath, nMgr);
			if (node == null)
			{
				return null;
			}
			return node.InnerText;
		}


		public string LoadXMLTemplate()
		{
			string XMLFile = string.Empty;
			// StreamWriter XMLWriter;
			OpenFileDialog sDlg = new OpenFileDialog();
			sDlg.InitialDirectory = Settings.Default.setTemplatePath;
			sDlg.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
			sDlg.FilterIndex = 1;
			sDlg.RestoreDirectory = true;
            string xmlData;
			try
			{
				if (sDlg.ShowDialog() == DialogResult.OK)
				{
					XMLFile = sDlg.FileName;
					StreamReader ResRd = new StreamReader(XMLFile);
					if (ResRd != null)
					{
						xmlData = ResRd.ReadToEnd();
						ResRd.Close();
						XmlDocument xdoc = new XmlDocument();
                        XmlDocument xTemp = new XmlDocument();
                        xTemp.LoadXml(xmlData);
// xdoc auf ebInterface untersuchen
                        XmlNode xmlnsebNode = xTemp.DocumentElement.Attributes.GetNamedItem("xmlns:eb");
                        if (xmlnsebNode == null)
                        {
                            MessageBox.Show("Die XML Datei enthälte keine ebInterface Definitionen. Die Vorlage wurde nicht geladen",
                                "XML Vorlage laden", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return (string.Empty); // XML Daten sind nicht gültig
                        }
                        string xmlnseb = xmlnsebNode.InnerText;
                        if (xmlnseb != PrefixURLeb)
                        {
                            string[] UriParts = xmlnseb.Split('/');
                            string loadVersion = @"/" + UriParts[UriParts.Length - 2] + @"/";
                            if (loadVersion == ebInterface_Version3p0)
                            {
                                string tmpStr = xmlData;
                                tmpStr = tmpStr.Replace(ebInterface_Version3p0, ebInterface_Version); // Alle 3p0 mit 3p02 ersetzen, Brutale Methode
                                // tmpStr = tmpStr.Replace(
                                xmlData = tmpStr;
                            }
                        }
                        xdoc.LoadXml(xmlData);
                        XmlNamespaceManager xNMgr = new XmlNamespaceManager(xdoc.NameTable);
						xNMgr.AddNamespace("eb", PrefixURLeb);
						xNMgr.AddNamespace("dsig", PrefixURLsig);
						string strGenSys = xdoc.DocumentElement.GetAttribute(xAttrGeneratingSystem);

						bool isValid = false;
						if ((strGenSys!=null)&&(strGenSys.Length >= _DocumentTitleVorlage.Length))
						{
							if (strGenSys.Substring(0, _DocumentTitleVorlage.Length) == _DocumentTitleVorlage)
							{
								isValid = true;
							}
						}
						if (isValid==false)
						{
							// ebDoc.ThisDocument.SetFehlerText(""); // XML nicht geladen.
							MessageBox.Show("Die XML Vorlage wurde nicht mit ebInterface 3.0 Word Formular Vorlage erstellt. Die Vorlage wurde nicht geladen",
								"XML Vorlage laden", MessageBoxButtons.OK, MessageBoxIcon.Error);
							return (string.Empty); // XML Daten sind nicht gültig
						}
                        int iret = CheckDate(xdoc.SelectSingleNode(xPathInvDate,xNMgr).InnerText);
                        DialogResult rc;
                        if (iret <0 )
                        {
                            rc = MessageBox.Show("Rechnungsdatum in der Vorlage ist veraltet. Soll das Rechnungsdatum auf " + DateTime.Today.ToShortDateString() + " gesetzt werden?",
                                "Vorlage laden", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                            if (rc==DialogResult.Yes)
                            {
                                ebDoc.ThisDocument.Rechnungsdatum = DateTime.Today;
                                ClearNodeContent(xdoc, xPathInvDate, xNMgr, FormatDate(ebDoc.ThisDocument.Rechnungsdatum));
                            }
                        }
                        iret = CheckDate(xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr).InnerText);
                        if (iret < 0)
                        {
                            rc = MessageBox.Show("Fälligkeitdatum in der Vorlage ist veraltet. Soll das Fälligkeitdatum auf " + DateTime.Today.ToShortDateString() + " gesetzt werden?",
                                "Vorlage laden", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                            if (rc == DialogResult.Yes)
                            {
                                ebDoc.ThisDocument.FaelligDatum = DateTime.Today;
                                ClearNodeContent(xdoc, xPathPaymtDuedate, xNMgr, FormatDate(ebDoc.ThisDocument.FaelligDatum));
                            }
                        }
                        string rnr = xdoc.SelectSingleNode(xPathInvNumber, xNMgr).InnerText;
                        if (rnr!="")
                        {
                            rc = MessageBox.Show("Die Vorlage enthält eine Rechnungsnummer. Soll die Rechnungsnummer gelöscht werden?",
                                                                "Vorlage laden", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                            if (rc==DialogResult.Yes)
                            {
                                ClearNodeContent(xdoc, xPathInvNumber, xNMgr, "");
                            }
                        }
                        
                        xmlData = MergeXML(xdoc, xNMgr);
						return (xmlData);
					}
				}

			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler beim Lesen der XML Vorlage "+XMLFile+"\n"+ex.Message,"Lesen XML Vorlage",MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
			return string.Empty;
		}


		#region Hilfefunktionen
        private int CheckDate(string xDate)
        {
            DateTime then = DateTime.Parse(xDate);
            return (DateTime.Compare(then, DateTime.Today));
        }

        private string MergeXML(XmlDocument xdocTemplate, XmlNamespaceManager xNmgr)
        {
            string LeerXml = ebDoc.ThisDocument.GetFromXMLResource(ebInterfaceLeer);
            string xmldata = "";
            XmlDocument xDocLeer = new XmlDocument();
            xDocLeer.LoadXml(LeerXml);
            XmlNamespaceManager xLeerNMgr = new XmlNamespaceManager(xDocLeer.NameTable);
            xLeerNMgr.AddNamespace("eb", PrefixURLeb);
            xLeerNMgr.AddNamespace("dsig", PrefixURLsig);
            Word.Document doc = ebDoc.ThisDocument.Application.ActiveDocument;
            XmlNode inDoc;
            XmlNode inTempl;
            foreach (Word.ContentControl wCC in doc.ContentControls)
            {
                string xPwCC = wCC.XMLMapping.XPath;
                if (xPwCC!=null)
                {
                    inDoc = xDocLeer.SelectSingleNode(xPwCC, xLeerNMgr);
                    if (inDoc==null)
                    {
                        throw new MissingFieldException("Merge Template: xPath=" + xPwCC + " in leerem XML nicht geunden.");
                    }
                    inTempl = xdocTemplate.SelectSingleNode(xPwCC, xNmgr);
                    if (inTempl!=null)
                    {
                        Debug.WriteLine(inDoc.Name+"="+inDoc.InnerText+"; "+inTempl.Name+"="+inTempl.InnerText);
                        inDoc.InnerText = inTempl.InnerText;
                    }
                }
            }
            // xPathItemList
            ReplaceLists(xPathItemList, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            // xPathTaxVATList
            ReplaceLists(xPathTaxVATList, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            // xPathDiscntPmntCond
            ReplaceLists(xPathDiscntPmntCond, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);

            // xPathBankLand xPathDocumentType xPathDocumentTitle xPathCurrency
            ReplaceLists(xPathBankLand, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            ReplaceLists(xPathDocumentType, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            ReplaceLists(xPathDocumentTitle, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            ReplaceLists(xPathCurrency, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);

            xmldata = xDocLeer.OuterXml;
            return xmldata;
        }
        private void CopyValue(string xPList, XmlDocument FromDoc, XmlNamespaceManager xFromNmgr, XmlDocument xToDoc, XmlNamespaceManager xToNmgr)
        {
            XmlNode xFromNode = FromDoc.SelectSingleNode(xPList, xFromNmgr);
            if (xFromNode == null)
            {
                return;
            }
            XmlNode xToNode = xToDoc.SelectSingleNode(xPList, xToNmgr);
            if (xToNode == null)
            {
                return;
            }

        }

        private void ReplaceLists(string xPList, XmlDocument FromDoc, XmlNamespaceManager xFromNmgr, XmlDocument xToDoc, XmlNamespaceManager xToNmgr)
        {
            XmlNode xFromNode = FromDoc.SelectSingleNode(xPList, xFromNmgr);
            if (xFromNode==null)
            {
                return;
            }
            XmlNode xToNode = xToDoc.SelectSingleNode(xPList, xToNmgr);
            if (xToNode==null)
            {
                return;
            }
            xToNode.InnerXml = xFromNode.InnerXml;
            return;
        }
		private void ClearNodeContent(XmlDocument xdoc, string xPathToClear, XmlNamespaceManager xNMgr, string value)
		{
			XmlNode xnode = xdoc.SelectSingleNode(xPathToClear, xNMgr);
			if (xnode!=null)
			{
				xnode.InnerText = value;
			}
		}
		public int SendMail(string ToAdress, string etresorAdress, string Subject, string MsgBody, string XmlFileName)
		{
			Outlook.Application outlook = new Outlook.Application();
			Outlook._MailItem mail = (Outlook._MailItem)outlook.CreateItem(Outlook.OlItemType.olMailItem);


			if (ToAdress != "")
			{
				mail.To = ToAdress;
				if (strEtresorAddress!="")
				{
					mail.BCC = strEtresorAddress;
				}
			}
			else
			{
				if (strEtresorAddress=="")
				{
					return 0;
				}
				mail.To = strEtresorAddress;
			}

			mail.Subject = Subject;
			mail.Body = MsgBody;
			mail.Attachments.Add(XmlFileName, Outlook.OlAttachmentType.olByValue, 1, null);

			// mail.Send();
			mail.Display(true);

			mail = null;
			outlook = null;
			return 0;

		}

		private string GetNameFromXMLError(string errorTxt)
		{
			string[] temp = errorTxt.Split('\t');
			return temp[0];
		}

		private string AppendRetVal(string oldval, string addval)
		{
			string retVal;
			if (oldval == "")
			{
				retVal = addval;
			}
			else
			{
				retVal = oldval+"\n" + addval;
			}
			return retVal;
		}

		/// <summary>
		/// Alle Eingabefelder prüfen
		/// </summary>
		/// <returns></returns>
		private string VerifyAllCC()
		{
			Word.Document wDoc = ebDoc.ThisDocument.Application.ActiveDocument;
			string retVal = string.Empty;
			foreach (Word.ContentControl wCC in wDoc.ContentControls)
			{
				Debug.WriteLine(wCC.ID+" "+wCC.PlaceholderText.Value + "/" + wCC.Tag + "<" + wCC.Range.Text);
				// Verifiy Fields
				switch (wCC.Tag)
				{
					case CCTag_NichtLeer:
						if ((wCC.ShowingPlaceholderText == true)||(wCC.Range.Text.Length==0))
						{
							retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "Darf nicht leer sein.");
						}
						break;
					case CCTag_VAT:
						if (ebDoc.ThisDocument.BetragInklMwSt>=10000)
						{
							if ((wCC.ShowingPlaceholderText==true)||(wCC.Range.Text=="00000000"))
							{
								retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "Empfänger VAT-ID fehlt bei Rechnungsbetrag>10000.");
							}
						}
						break;
					case CCTag_Num:
						if (wCC.ShowingPlaceholderText != true)
						{
							try
							{
								decimal decVal = decimal.Parse(wCC.Range.Text);
							}
							catch (Exception)
							{
								retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "ist nicht numerisch.");
							}
						}
						else 
						{
							retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "Darf nicht leer sein.");
						}
						break;
					default:
						break;
				}
				if (wCC.XMLMapping.XPath==xPathPaymtDuedate)
				{
					// Fälligkeitsdatum muss => Rechnungsdatum sein
					if (VerifyDueDate(FormatDateVonXML(wCC.Range.Text))==false)
					{
						retVal = AppendRetVal(retVal, "Fälligkeitsdatum\t Das Datum liegt vor dem Rechnungsdatum.");
					}

				}
			}
			return retVal;
		}

		private bool VerifyDueDate(string dueDate)
		{
			DateTime dtDueDate = DateTime.Parse(dueDate);
			DateTime dtInvDate = DateTime.Parse(ebDoc.ThisDocument.CC_InvoiceDate.Text);
			if (DateTime.Compare(dtDueDate,dtInvDate)<0)
			{
				return false;
			}
			return true;
		}
		private Word.ContentControl FindCCfromXMLMapping(string name)
		{
			Word.Document wDoc = ebDoc.ThisDocument.Application.ActiveDocument;
			foreach (Word.ContentControl wCC in wDoc.ContentControls)
			{
				
				if (wCC.XMLMapping.XPath == name)
				{
					return wCC;
				}
			}
			return null;
		}
		private string GetPlaceholderText4Error(string eText)
		{
			string wCCName;
			Word.ContentControl wCCTemp;
			wCCName = GetNameFromXMLError(eText);
			if (wCCName == "")
			{
				return ("?Name unbekannt?");
			}
			wCCTemp = FindCCfromXMLMapping(wCCName);
			if (wCCTemp==null)
			{
				return ("?XMLMapping unbekannt?");
			}
			return (wCCTemp.PlaceholderText.Value);

		}


		private XmlSchemaSet GetXmlSchemas()
		{
			XmlSchemaSet xSchema = new XmlSchemaSet();
			try
			{
				Assembly Asm = Assembly.GetExecutingAssembly();
				using (System.Xml.XmlReader rdr = System.Xml.XmlReader.Create(Asm.GetManifestResourceStream(xmlDsigXSDFile)))
				{
				  xSchema.Add(PrefixURLsig, rdr);
				}
				using (System.Xml.XmlReader rdr = System.Xml.XmlReader.Create(Asm.GetManifestResourceStream(InvoiceXSDFile)))
				{
				  xSchema.Add(PrefixURLeb, rdr);
				}
				return xSchema;

			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler bei Add Schema\r\n" + ex.Message);

			}
			return null;
		}

		private bool IsEbInterfaceXMLValid(XmlDocument xdoc, string filename, bool isDoc)
		{
			XmlValidator xmlChecker = new XmlValidator();
			XmlValidator.XmlValidatorResult result;
			ebDoc.ThisDocument.SetFehlerText(""); // Fehlerliste löschen
			string errorTxt = string.Empty;
			string temp = string.Empty;
			try
			{
				xmlChecker.SchemaSet = GetXmlSchemas();

				if (isDoc==true)
				{
					result = xmlChecker.ValidateXmlDocument(xdoc, ValidationType.Schema, null);
					
				}
				else
				{
					result = xmlChecker.ValidateXmlFile(filename, ValidationType.Schema, null);
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler bei XML Validierung von '" + xdoc + "'.\r\n" +
								ex.Message + "\r\n",
				"XML Validieren", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			

			switch (result)
			{
				case XmlValidator.XmlValidatorResult.Valid:
					return true;
					break;
				case XmlValidator.XmlValidatorResult.ErrorsExists:
					errorTxt = "Fehler im XML Dokument '"+xdoc+"'.\r\n";
					for (int i = 0; i < xmlChecker.Errors.Count; i++)
					{
						temp = xmlChecker.Errors[i].ToString();
						temp = GetPlaceholderText4Error(temp) + "\t" + temp;
						errorTxt = errorTxt+"\r\n" + temp;
					}
					if (xmlChecker.Warnings.Count > 0)
					{
						errorTxt = errorTxt + "\r\nWarnungen im XML Dokument '" + xdoc + "'.\r\n";
						for (int i = 0; i < xmlChecker.Warnings.Count; i++)
						{
							temp = xmlChecker.Warnings[i].ToString();
							temp = GetPlaceholderText4Error(temp) + "\t" + temp;
							errorTxt = errorTxt + "\r\n" + temp;
						}
					}

					Debug.WriteLine(errorTxt);
					// MessageBox.Show(errorTxt);
					ebDoc.ThisDocument.SetFehlerText(errorTxt);
					return false;
					// break;
				case XmlValidator.XmlValidatorResult.WarningsExists:
					errorTxt = "Warnungen im XML Dokument '" + xdoc + "'.\r\n";
					for (int i = 0; i < xmlChecker.Warnings.Count; i++)
					{
						temp = xmlChecker.Warnings[i].ToString();
						temp = GetPlaceholderText4Error(temp) + "\t" + temp;
						errorTxt = errorTxt + "\r\n" + temp;
					}
					Debug.WriteLine(errorTxt);
					// MessageBox.Show(errorTxt);
					ebDoc.ThisDocument.SetFehlerText(errorTxt);
					return true;
					// break;
				default:
					break;
			}
			return false;
		}
		public string GetNodeValue(Office.CustomXMLPart XMLPart, string xPathList, string XMLFieldName, int i)
		{
			string XMLField = string.Empty;
			string value = string.Empty;
			XMLField = string.Format(xPathList + "[{0}]", i + 1) + "/" + XMLFieldName;
			Office.CustomXMLNode xn = XMLPart.SelectSingleNode(XMLField);
			value = xn.Text;
			return (value);
		}

		private string FormatDecimal(decimal val)
		{
			string retval = val.ToString("#0.00", System.Globalization.CultureInfo.InvariantCulture);
			return (retval);
		}

		private string FormatDateVonXML(string datum)
		{
			if (datum=="")
			{
				return datum;
			}
			try
			{
				string rdat = FormatDate(DateTime.Parse(datum));
				return rdat;
			}
			catch (Exception ex)
			{
				return "";
			}
		}

		private string FormatDate(DateTime datum)
		{
			string retval = datum.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
			return retval;
		}

		private decimal ConvertXML2Decimal(string wert)
		{
			if (wert == "")
			{
				return (0);
			}
			string wert2 = wert.Replace(".", ",");
			decimal dec = decimal.Parse(wert2);
			return (dec);

		#endregion
		}
		/// <summary>
		/// Erzeugt aus der Detail Tabelle die XML Ausgabe
		/// </summary>
		/// <returns></returns>
		public string Details2XML()
		{
			string position;        // 0
			string Beschreibung;    // 1
			string ArtikelNr;       // 2
			string Einheit;         // 3
			string Menge;           // 4
			string stueckpreis;     // 5
			string mwst;            // 6
			string RabattFlag;      // 7
			string Rabatt;          // 8
			string gesamtbetrag;    // 9


			string NodeValue = string.Empty;

			try
			{
				DataRow[] rows = InvDetails.TblInvDetails.Select();
				int i = 1;
				foreach (DsInvoice.TblInvDetailsRow dsRow in rows)
				{
					ArtikelNr = dsRow.SpArtikelNr;
					Menge = FormatDecimal(dsRow.SpMenge);
					Beschreibung = dsRow.SpBezeichnung;
					stueckpreis = FormatDecimal(dsRow.SpEinzelpreis);
					Einheit = dsRow.SpEinheit;
					position = (i++).ToString();
					gesamtbetrag = FormatDecimal(dsRow.SpGesamtBetrag);
					mwst = FormatDecimal(dsRow.SpMwSt);
					Rabatt = FormatDecimal(dsRow.SpRabattProz);
					RabattFlag = "false";
					if (dsRow.SpRabattProz != 0)
					{
						RabattFlag = "true";
					}

					NodeValue = NodeValue + string.Format(DetailItemXml,
								position,        // 0
								Beschreibung,    // 1
								ArtikelNr,       // 2
								Einheit,         // 3
								Menge,           // 4
								stueckpreis,     // 5
								mwst,            // 6
								RabattFlag,      // 7
								Rabatt,          // 8
								gesamtbetrag    // 9
								);
				}

			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler bei Erstellen der XML für Detailzeilen" + ex.Message, "XML Erstellen", MessageBoxButtons.OK, MessageBoxIcon.Error);
				throw;
			}

			return (NodeValue);
		}

		public string MwSt2XML()
		{
			string NodeValue = string.Empty;

			try
			{
				DataRow[] dsRows = InvDetails.TblMwStSummen.Select();
				foreach (DsInvoice.TblMwStSummenRow row in dsRows)
				{
					NodeValue = NodeValue + string.Format(VatItemXML,
						FormatDecimal(row.spBasisBetrag),
						FormatDecimal(row.spMwSt),
						FormatDecimal(row.spMwStBetrag));
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler bei Erstellen XML für MwST." + ex.Message, "XML Erstellen", MessageBoxButtons.OK, MessageBoxIcon.Error);
				throw;
			}
			return (NodeValue);
		}

		public string Skonto2XML()
		{
			string NodeValue = string.Empty;

			try
			{
				DataRow[] dsRows = InvDetails.TblInvSkonto.Select();
				foreach (DsInvoice.TblInvSkontoRow row in dsRows)
				{
					NodeValue = NodeValue + string.Format(DiscItemXML,
						FormatDate(row.SpBisDatum),
						FormatDecimal(row.SpSkontoProz),
						FormatDecimal(row.spSkontoBetrag));
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show("Fehler bei Erstellen XML für Skonto." + ex.Message, "XML Erstellen", MessageBoxButtons.OK, MessageBoxIcon.Error);
				throw;
			}
			return (NodeValue);
		}
		public void LoadSkontoTable(Office.CustomXMLPart XMLPart, DsInvoice myDs)
		{
			decimal SktoPrz;
			DateTime SktoDate;
			DsInvoice.TblInvSkontoRow myRow;
			string ReDatum = ebDoc.ThisDocument.GetInvoiceDate();
			if (ReDatum != "")
			{
				try
				{
					ebDoc.ThisDocument.Rechnungsdatum = DateTime.Parse(ReDatum);
				}
				catch (Exception ex)
				{
					ebDoc.ThisDocument.Rechnungsdatum = DateTime.Today;
				}
			}


			try
			{
				myDs.TblInvSkonto.Clear();
				int icnt = XMLPart.SelectNodes(xPathDiscntLine).Count;
				for (int i = 0; i < icnt; i++)
				{
					string StrSktoPrz = GetNodeValue(XMLPart, xPathDiscntLine, xPathDiscntProz, i);
					if (StrSktoPrz != "")
					{
						SktoPrz = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathDiscntLine, xPathDiscntProz, i));
						SktoDate = DateTime.Parse(GetNodeValue(XMLPart, xPathDiscntLine, xPathDiscntDate, i));
						myRow = (DsInvoice.TblInvSkontoRow)myDs.TblInvSkonto.Rows.Add(new object[] { SktoPrz, SktoDate, 0, 0, 0 });
						myDs.TblInvSkonto.UpdateSkontoTage(myRow);
					}
				}

			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}


		}

		public bool LoadDetailsTable(Office.CustomXMLPart XMLPart, DsInvoice myDs)
		{
			decimal Menge;
			decimal RabattProz;
			string ArtikelNr;
			string Beschreibung;
			decimal stueckpreis;
			string Einheit;
			decimal Mwst;

			try
			{
				myDs.TblInvDetails.Clear();
				int icnt = XMLPart.SelectNodes(xPathListLine).Count;

				// DsDetails myDS = new DsDetails();


				for (int i = 0; i < icnt; i++)
				{
					string StrMenge = GetNodeValue(XMLPart, xPathListLine, xPathQuantity, i);
					if (StrMenge != "")
					{
						Menge = ConvertXML2Decimal(StrMenge);
						RabattProz = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathListLine, xPathReductionRate, i));
						ArtikelNr = GetNodeValue(XMLPart, xPathListLine, xPathArtikelNr, i);
						Beschreibung = GetNodeValue(XMLPart, xPathListLine, xPathDesc, i);
						stueckpreis = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathListLine, xPathUnitPrice, i));
						Mwst = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathListLine, xPathTaxRate, i));
						if (ebDoc.ThisDocument.IsMwStInSettings(Mwst)==false)
						{
							throw (new Exception("Der MwSt Satz "+Mwst.ToString("0.00")+" in der XML Vorlage ist nicht in den aktuellen Einstellungen eingetragen.\n"+
								"Ergänzen Sie die MwSt Tabelle in den Einstellungen um diesen Wert und laden Sie dann die XML Vorlage erneut."));
						}
						Einheit = GetNodeValue(XMLPart, xPathListLine, xPathUnit, i);
						DsInvoice.TblInvDetailsRow myRow = (DsInvoice.TblInvDetailsRow)myDs.TblInvDetails.Rows.Add();
						myRow.SpMenge = Menge;
						myRow.SpArtikelNr = ArtikelNr;
						myRow.SpBezeichnung = Beschreibung;
						myRow.SpEinzelpreis = stueckpreis;
						myRow.SpEinheit = Einheit;
						myRow.SpRabattProz = RabattProz;
						myRow.SpMwSt = Mwst;
					}                
				}

			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
				return false;
			}

			return true;
		}

	}
}
